using System;
using System.Security.Cryptography;
using System.Data;
using System.Collections;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Text;
using Microsoft.SqlServer.Management.Smo;

/// <summary>
/// Summary description for Common
/// </summary>
namespace SqlWebAdmin.CSharp
{
    public class Common
    {
        private Common()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        public static string ConcatenateExceptions(Exception exc)
        {
            StringBuilder sb = new StringBuilder();
            Exception cur;

			int i = 0;
            cur = exc;

            if (cur != null)
                sb.Append(Common.ConcatenateExceptions(cur.InnerException));

            while (cur != null)
            {
                sb.Append (" --> ");
                sb.Append(cur.Message);
                cur = cur.InnerException;
				i++;
            }

		//	sb.Append("<br>");
            return sb.ToString();
        }

		private static string Spaces(int x)
		{
			string tmp = "";
			for (int i = 0; i < x; i++)
			{
				tmp = tmp + "     ";
			}

			return tmp;
		}

		public static DataType NewDataType(string dataTypeName, Int32 length, Int32 prec, Int32 scale, string typeName, string typeSchema)
        {
            DataType dt = null;


            switch (dataTypeName)
            {
                case "bigint":
                    dt = DataType.BigInt;
                    break;
                case "binary":
                    dt = DataType.Binary(length);
                    break;
                case "bit":
                    dt = DataType.Bit;
                    break;
                case "char":
                    dt = DataType.Char(length);
                    break;
                case "datetime":
                    dt = DataType.DateTime;
                    break;
                case "decimal":
                    dt = DataType.Decimal(prec, scale);
                    break;
                case "float":
                    dt = DataType.Float;
                    break;
                case "image":
                    dt = DataType.Image;
                    break;
                case "int":
                    dt = DataType.Int;
                    break;
                case "money":
                    dt = DataType.Money;
                    break;
                case "nchar":
                    dt = DataType.NChar(length);
                    break;
                case "ntext":
                    dt = DataType.NText;
                    break;
                case "numeric":
                    dt = DataType.Decimal(prec, scale);
                    break;
                case "nvarchar":
                    dt = DataType.NVarChar(length);
                    break;
                case "nvarchar(max)":
                    dt = DataType.NVarCharMax;
                    break;
                case "real":
                    dt = DataType.Real;
                    break;
                case "smalldatetime":
                    dt = DataType.SmallDateTime;
                    break;
                case "smallint":
                    dt = DataType.SmallInt;
                    break;
                case "smallmoney":
                    dt = DataType.SmallMoney;
                    break;
                case "sql_variant":
                    dt = DataType.Variant;
                    break;
                case "text":
                    dt = DataType.Text;
                    break;
                case "timestamp":
                    dt = DataType.Timestamp;
                    break;
                case "tinyint":
                    dt = DataType.TinyInt;
                    break;
                case "uniqueidentifier":
                    dt = DataType.UniqueIdentifier;
                    break;
                case "userdefineddatatype":
                    dt = DataType.UserDefinedDataType(typeName, typeSchema);
                    break;
                case "userdefinedtype":
                    dt = DataType.UserDefinedType(typeName, typeSchema);
                    break;
                case "varbinary":
                    dt = DataType.VarBinary(length);
                    break;
                case "varchar":
                    dt = DataType.VarChar(length);
                    break;
                case "varchar(max)":
                    dt = DataType.VarCharMax;
                    break;
                case "xml":
                    if (typeName.Trim().Length > 0)
                    {
                        dt = DataType.Xml(typeName);
                    }
                    else
                    {
                        dt = new DataType();
                        dt.SqlDataType = SqlDataType.Xml;
                    }

                    break;

            }

            return dt;
        }

        public static SiteMapNode ExpandPath(Object sender, SiteMapResolveEventArgs e)
        {

            //Obtain a reference to the current node and its ancestors
            SiteMapNode nodeCopy = SiteMap.CurrentNode.Clone(true);

            //The temporary node is used for walking up the chain of nodes, fixing up Urls and
            //other properties along the way.
            SiteMapNode tempNode = nodeCopy;

            //Check if there is a newsgroup type in the query string
            string typeID = null;
            string typeIDUrlEncoded = null;
            if (!String.IsNullOrEmpty(e.Context.Request.QueryString[QueryStringKeys.Database]))
            {
                typeID = e.Context.Server.HtmlEncode(e.Context.Request.QueryString[QueryStringKeys.Database]);
                typeIDUrlEncoded = e.Context.Server.UrlEncode(e.Context.Request.QueryString[QueryStringKeys.Database]);
            }

            //First perform Url fixups for the postings page
            //If there is a posting ID in the query string, then we know the current node
            //is the postings page.
            if (!String.IsNullOrEmpty(e.Context.Request.QueryString[QueryStringKeys.Table]))
            {
                string postingID =
                    e.Context.Server.HtmlEncode(e.Context.Request.QueryString[QueryStringKeys.Table]);
                string postingIDUrlEncoded =
                    e.Context.Server.UrlEncode(e.Context.Request.QueryString[QueryStringKeys.Table]);

                string newUrl = tempNode.Url + "?database=" + typeIDUrlEncoded + "&table=" + postingIDUrlEncoded;
                string newTitle = tempNode.Title + ": " + postingID;

                tempNode.Url = newUrl;
                tempNode.Title = newTitle;

                //Walkup one level to the parent
                tempNode = tempNode.ParentNode;
            }

            //Next, perform fixups for the newsgroup page
            //By this point the nodeCopy variable is pointing at the newsgroup node
            if (!String.IsNullOrEmpty(e.Context.Request.QueryString[QueryStringKeys.Database]))
            {
                string newUrl = tempNode.Url + "?database=" + typeIDUrlEncoded;
                string newTitle = tempNode.Title + ":  " + typeID;

                tempNode.Url = newUrl;
                tempNode.Title = newTitle;
            }

            //Lastly, return the current node
            return nodeCopy;


/*
            if (SiteMap.CurrentNode == null) return null;

            // obtain a reference to the current node and it's ancestors
            SiteMapNode nodeCopy = SiteMap.CurrentNode.Clone(true);

            // walk backwards through the heirarchy until we reach the root node, we'll
            // ignore the root node
            SiteMapNode currentNode = nodeCopy;
            while (currentNode.ParentNode != null )
            {
                currentNode.Title = "ZZZZZZZZZZZZZ";

                // check if the current node is using query string keys. If so
                // we need to change the name of this node to a value from the query
                // string 
                //
                // for example : if the node is using the querystring keys "database"
                // then we don't want to display "database" but we want to display the
                // actual database name from the query string.
                //
                // Since the query string keys doesn't carry a heirarchy with it, well
                // have to assume that the query string keys are listed from general 
                // to specific order so we'll just take the last key, though we'll ignore
                // the "schema" query string key
                if (currentNode["queryStringKeys"] != null)
                {
                    string[] keys = currentNode["queryStringKeys"].Split(',');
                    if (keys != null)
                    {
                        for( int count = keys.Length - 1; count >= 0; count-- )
                        {
                            if( keys[count] != null && keys[count] != "schema" )
                            {
                                string key = keys[count];
                                if (HttpContext.Current.Request.QueryString[key] != null)
                                {
                                    currentNode.Title = HttpUtility.HtmlEncode(HttpUtility.UrlDecode(HttpContext.Current.Request.QueryString[key]));
                                }
                                break;
                            }
                        }
                    }
                }

                currentNode = currentNode.ParentNode;                
                
            }

            if (currentNode.Title == nodeCopy.RootNode.Title)
                currentNode.Title = string.Empty;
*/
            return nodeCopy;
        }

		public static bool UserHasAccess(SiteMapNode node)
		{
			bool userHasAccess = false;

			IList roles = node.Roles;
			if (roles.Count > 0)
			{
				for (int j = 0; j < roles.Count; j++)
				{
					userHasAccess = Roles.IsUserInRole(roles[j].ToString());
					if (userHasAccess)
						break;
				}
			}
			else
			{
				// no roles
				userHasAccess = true;
			}

			return userHasAccess;
		}	 

    }

} 